package com.desay.pangoo.itmt.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

import javax.persistence.*;

import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.Data;

/**
 * @author uidq1163 on [2022年09月22日上午10:16:03] <br>
 *         work group Tech classification 工作组技术分类:技术相信信息
 * @Modified By： [修改人] on [修改日期] for [修改说明]
 */
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "tech_project_info", uniqueConstraints = { @UniqueConstraint(columnNames = { "tech_ptn" }) })
@Data
public class TechProjectInfoEntity extends BaseEntity implements Serializable {

	private static final long serialVersionUID = 4309236143738230241L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", columnDefinition = "bigint COMMENT '主键'")
	private Long id;

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "tech_class_id")
	private TechClassificationEntity techClass;

	@Column(name = "tech_ptn", nullable = false, columnDefinition = "varchar(255) COMMENT '技术编号'")
	private String techPtn;

	@Column(name = "research_forms", nullable = false, columnDefinition = "text COMMENT '研究形式'")
	private String researchForms;

	@Column(name = "tech_name", nullable = false, columnDefinition = "text COMMENT '技术名称'")
	private String techName;

	@Column(name = "subsidiary", columnDefinition = "text COMMENT '子技术'")
	private String subsidiary;

	@Column(name = "description", columnDefinition = "mediumtext COMMENT '说明'")
	private String description;

	@Column(name = "tech_level", nullable = false, columnDefinition = "int COMMENT '技术等级:核心:1，关键:2，通用:3，一般:4'")
	private Integer techLevel;

	@Column(name = "priority", nullable = false, columnDefinition = "varchar(50) COMMENT '优先级'")
	private String priority;

	/**
	 * 项目对应的时间线状态
	 */
	@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
	@JoinColumn(name = "tech_project_id")
	@OrderBy("year,quarter")
	@JsonIgnoreProperties({ "techProject" })
	private Set<TechYearQuarterEntity> techYearQuarters;

	@Column(name = "quantitative_indicators", columnDefinition = "mediumtext COMMENT '量化指标'")
	private String quantitativeIndicators;

	@Column(name = "tmt_approval", columnDefinition = "varchar(50) COMMENT 'TMT 评审'")
	private String tMTApproval;

	@Column(name = "maturity", columnDefinition = "varchar(50) COMMENT '技术状态'")
	private String maturity;

	/**
	 * 技术成熟度:理论阶段（Conceptual）、原型阶段（Prototype）、商业推广阶段（Commercial）、成熟技术（Mature）
	 */
	@Column(name = "tech_maturity", columnDefinition = "varchar(50) COMMENT '技术成熟度'")
	private String techMaturity;

	/** 重点项目 */
	@Column(name = "is_major_project", columnDefinition = "bit(1) default 0 COMMENT '重点项目'")
	private Boolean isMajorProject;

	@Column(name = "requirement_source", columnDefinition = "text COMMENT '需求来源'")
	private String requirementSource;

	@Column(name = "developed_by", columnDefinition = "text COMMENT '开发负责人'")
	private String developedBy;

	/**
	 * 设备需求
	 */
	@Column(name = "tools_equipment", columnDefinition = "text COMMENT '设备需求'")
	private String toolsEquipment;
	/**
	 * 资源需求(人月）
	 */
	@Column(name = "resource_needed", columnDefinition = "float(11,1) COMMENT '资源需求(人月）'")
	private Float resourceNeeded;

	@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", cascade = { CascadeType.REFRESH, CascadeType.REMOVE,
			CascadeType.MERGE })
	@JsonIgnoreProperties({ "parent" })
	private Set<TechProjectInfoEntity> children = new HashSet<>(16);

	@ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.REFRESH }, optional = true)
	@JoinColumn(name = "parent_id")
	@JsonIgnoreProperties({ "children" })
	private TechProjectInfoEntity parent;

	/**
	 * 课题是否关联提案申请
	 */
	@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.REFRESH }, optional = true)
	@JoinColumn(name = "tech_online_review_id")
	@JsonIgnoreProperties({ "techProjects", "files", "children", "parent" })
	private TechOnlineReviewEntity techOnlineReview;

	/**
	 * 课题审核状态
	 */
	@Column(name = "audit_status", columnDefinition = "int(2) default 1 COMMENT '审核状态：1待审核，2审核通过，3审核拒绝'")
	private Integer auditorStatus;

	/**
	 * 审核时间
	 */
	@Column(name = "audit_time", columnDefinition = "datetime COMMENT '审核时间'")
	private Date auditorTime;

	/**
	 * 审核者
	 */
	@Column(name = "auditor", columnDefinition = "varchar(255) COMMENT '审核者'")
	private String auditor;

	@Column(name = "plan_budgeting", columnDefinition = "float(11,1) COMMENT '课题规划费用预算'")
	private Float planBudgeting;

	@Column(name = "human_budgeting", columnDefinition = "float(11,1) COMMENT '课题规划人力预算：折换成钱'")
	private Float humanBudgeting;

	@Column(name = "budgeting", columnDefinition = "float(20,1) COMMENT '总预算'")
	private Float budgeting;

	/**
	 * 应用平台
	 */
	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "ref_project_platform_bu", joinColumns = {
			@JoinColumn(name = "project_id") }, inverseJoinColumns = {
					@JoinColumn(name = "bu_id") }, uniqueConstraints = {
							@UniqueConstraint(columnNames = { "project_id", "bu_id" }) })
	private Set<ProjectBUEntity> platforms;

	/**
	 * 开发责任主体
	 */
	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "ref_project_duty_bu_div", joinColumns = {
			@JoinColumn(name = "review_id") }, inverseJoinColumns = {
					@JoinColumn(name = "bu_id") }, uniqueConstraints = {
							@UniqueConstraint(columnNames = { "review_id", "bu_id" }) })
	private Set<BUDivEntity> dutyBuss;

	/**
	 * 相关BU
	 */
	@ManyToMany(fetch = FetchType.EAGER)
	@JoinTable(name = "ref_project_relevance_bu_div", joinColumns = {
			@JoinColumn(name = "review_id") }, inverseJoinColumns = {
					@JoinColumn(name = "bu_id") }, uniqueConstraints = {
							@UniqueConstraint(columnNames = { "review_id", "bu_id" }) })
	private Set<BUDivEntity> relevanceBuss;

	/**
	 * ALM需求编号
	 */
	@Column(name = "alm_code", columnDefinition = "varchar(250) COMMENT 'ALM需求编号'")
	private String almCode;

	/**
	 * 技术交付评审
	 */
	@Column(name = "delivery_review", columnDefinition = "varchar(20) default '-' COMMENT '技术交付评审'")
	private String deliveryReview;

	/**
	 * 项目专利信息
	 */
	@OneToOne(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval = true)
	@JoinColumn(name = "patent_id")
	private PatentEntity patent;

	/**
	 * 关联项目信息
	 */
	@OneToOne(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval = true)
	@JoinColumn(name = "project_id")
	private ProjectEntity project;

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + Objects.hash(id);
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (!super.equals(obj)) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		TechProjectInfoEntity other = (TechProjectInfoEntity) obj;
		return Objects.equals(auditor, other.auditor) && Objects.equals(auditorStatus, other.auditorStatus)
				&& Objects.equals(auditorTime, other.auditorTime) && Objects.equals(budgeting, other.budgeting)
				&& Objects.equals(description, other.description) && Objects.equals(developedBy, other.developedBy)
				&& Objects.equals(humanBudgeting, other.humanBudgeting) && Objects.equals(id, other.id)
				&& Objects.equals(maturity, other.maturity) && Objects.equals(planBudgeting, other.planBudgeting)
				&& Objects.equals(priority, other.priority)
				&& Objects.equals(quantitativeIndicators, other.quantitativeIndicators)
				&& Objects.equals(requirementSource, other.requirementSource)
				&& Objects.equals(researchForms, other.researchForms)
				&& Objects.equals(resourceNeeded, other.resourceNeeded) && Objects.equals(subsidiary, other.subsidiary)
				&& Objects.equals(tMTApproval, other.tMTApproval) && Objects.equals(techClass, other.techClass)
				&& Objects.equals(techLevel, other.techLevel) && Objects.equals(techName, other.techName)
				&& Objects.equals(techPtn, other.techPtn) && Objects.equals(techYearQuarters, other.techYearQuarters)
				&& Objects.equals(toolsEquipment, other.toolsEquipment);
	}

	/**
	 * 删除级联中间表关联数据
	 */
	public void remove() {
		this.relevanceBuss.clear();
		this.dutyBuss.clear();
		this.platforms.clear();
	}
}
